﻿using System;
using System.IO;
using System.Threading;

namespace iTool.Utils
{
    public class iObserverbalFileChange
    {
        /// <summary>
        /// 定时器触发间隔
        /// </summary>
        const int TimeoutMillis = 1000;

        private FileSystemWatcher watcher = new FileSystemWatcher();

        private Timer Timer = null;

        public event EventHandler<string> OnChange;

        /// <param name="StrWarcherPath">需要监听的目录</param>
        /// <param name="FilterType">需要监听的文件类型(筛选器字符串)</param>
        /// <param name="IsEnableRaising">是否启用监听</param>
        /// <param name="IsInclude">是否监听子目录</param>
        public iObserverbalFileChange(string warcherPath, string filterType, bool isEnableRaising, bool isInclude)
        {
            //设置定时器的回调函数。此时定时器未启动
            Timer = new Timer(new TimerCallback(this.OnWatchedFileChange), null, Timeout.Infinite, Timeout.Infinite);
            this.WatcherStart(warcherPath, filterType, isEnableRaising, isInclude);
        }

        private void WatcherStart(string StrWarcherPath, string FilterType, bool IsEnableRaising, bool IsInclude)
        {
            watcher.BeginInit();
            if (!string.IsNullOrWhiteSpace(FilterType))
            {
                watcher.Filter = FilterType;
            }
            watcher.IncludeSubdirectories = IsInclude;
            watcher.EnableRaisingEvents = IsEnableRaising;
            watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size;
            watcher.Path = StrWarcherPath;
            watcher.Created += new FileSystemEventHandler((sender, e) => Timer.Change(TimeoutMillis, Timeout.Infinite));
            watcher.Changed += (sender, e) => Timer.Change(TimeoutMillis, Timeout.Infinite);
            watcher.Deleted += (sender, e) => Timer.Change(TimeoutMillis, Timeout.Infinite);
            watcher.Renamed += (sender, e) => Timer.Change(TimeoutMillis, Timeout.Infinite);
            watcher.EndInit();
        }


        public void Stop()
        {
            watcher.EnableRaisingEvents = false;
        }

        private void OnWatchedFileChange(object? state)
        {
            if (this.OnChange != null)
            {
                this.OnChange.Invoke(this, string.Empty);
            }
        }
    }
}


